#pragma once
#include "afxwin.h"
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl\glaux.h>								// Header File For The GLaux Library

#include <vector>
#include <string>

#include "DSVector3d.h"

//Reference:
//1.http://blog.sina.com.cn/s/blog_6ac675410100o0t6.html
//2.http://www.codeguru.com/cpp/cpp/cpp_mfc/tutorials/article.php/c10975__2/Setting-Up-OpenGL-in-an-MFC-Control.htm
//3.NeHe L13 - Draw text: http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=13

class DSGLDRAWER_API COpenGLDrawer :	public CWnd
{
	public:
		static const int DS_GL_TIMER_ID = 1001;
		static const int DS_GL_UPDATE_FREQUENCY = 100;		//ms
		static const int DS_GL_MAX_TEXTURE = 256;

//================ Data member ==================
	public:
	//timer
		UINT_PTR m_unpTimer;

	//Max/Min Window
		bool m_bIsMaximized;
		BOOL m_IsEnableMouseMovementDetection;

//------------------ Set Font Head ---------------
//BOOK:Draw Font
		GLuint m_gluiBaseDisplayList;				//For the font set
																		//base will hold the number of the first display list we create. Each character requires it's own display list. 
																		//The character 'A' is 65 in the display list, 'B' is 66, 'C' is 67, etc. So 'A' would be stored in display list base+65. 
		
//------------------ Set Font Foot  ---------------
	protected:
//Window Information - for draw scene
		CWnd *m_hWnd;
		HDC m_hdc;
		HGLRC	m_hrc;
		int m_nPixelFormat;
		CRect m_rect;						//For get window rect
		CRect m_rectOldWindow;
		CRect m_rectOrgRect;

		GLsizei m_glnWidth;
		GLsizei m_glnHeight;
		GLdouble m_gldAspect;

//Texture
		//std::vector<GLuint> m_vglTextureList;
		GLuint m_glTextureList[DS_GL_MAX_TEXTURE];
		std::vector<std::string> m_vstrTextureFilePath;

// View information variables if camera - for mouse move
		float m_fLastX;
		float m_fLastY;
		float m_fPosX;
		float m_fPosY;
		float m_fPosZ;
		float m_fZoom;
		float m_fRotX;
		float m_fRotY;
		bool m_IsEnableRotate;
		bool m_IsEnableZoom;

//============== Member Function =================
	public:
		COpenGLDrawer(void);
		~COpenGLDrawer(void);

		void glCreate(CRect rect, CWnd *parent);
		GLvoid glPrint(GLfloat x, GLfloat y, const char* szFormat, ...);

		CDSVector3d ConvertWinPos2ViewportPos(int x, int y);
		
		inline void EnableRotate(bool IsEnable = true) { m_IsEnableRotate = IsEnable; };
		inline void EnableZoom(bool IsEnable = true) { m_IsEnableZoom = IsEnable; };

		bool ReloadGLTexture(void);
		bool RemoveTextureResource(const char* szFilePath);

	protected:
		void glInitialize(void);
		virtual void glDrawScene(void) = 0;

		GLvoid glBuidFont(GLvoid);
		GLvoid glKillFont(GLvoid);

//BMP
		AUX_RGBImageRec *LoadBMP(const char *szFilePath);
		int LoadGLTextures(std::vector<std::string> vstrFilePaths);

//================ Properties ====================
	public:
		inline void AddTextureFilePath(const char* szFilePath) {
			m_vstrTextureFilePath.push_back(szFilePath);
		};

	public:
		DECLARE_MESSAGE_MAP()
//============ MFC ====================
		afx_msg void OnPaint();
		afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
		afx_msg void OnDraw(CDC *pDC);
		afx_msg void OnTimer(UINT_PTR nIDEvent);

	public:
		afx_msg void OnSize(UINT nType, int cx, int cy);
		afx_msg void OnMouseMove(UINT nFlags, CPoint point);
		afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);

		afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
		afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
		afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
		afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
};
